package com.sky.service.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.service.WorkspaceService;
import com.sky.vo.*;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
public class ReportServiceImpl implements ReportService {
	
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private OrderMapper orderMapper;
	@Autowired
	private WorkspaceService workspaceService;
	
	/**
	 * 营业额统计
	 *
	 * @param begin
	 * @param end
	 * @return
	 */
	@Override
	public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
		List<LocalDate> time = new ArrayList<>();
		List<Double> sum = new ArrayList<>();
		time.add(begin);
		while (!begin.equals(end)) {
			Double turnover = orderMapper.sumAmount(Orders.COMPLETED, LocalDateTime.of(begin, LocalTime.MIN),
				LocalDateTime.of(begin, LocalTime.MAX));
			sum.add(turnover == null ? 0.0 : turnover);
			begin = begin.plusDays(1);
			time.add(begin);
		}
		Double v = orderMapper.sumAmount(Orders.COMPLETED, LocalDateTime.of(end, LocalTime.MIN),
			LocalDateTime.of(end, LocalTime.MAX));
		sum.add(v == null ? 0.0 : v);
		return new TurnoverReportVO(StringUtils.join(time, ","), StringUtils.join(sum, ","));
	}
	
	/**
	 * 用户统计
	 *
	 * @param begin
	 * @param end
	 * @return
	 */
	@Override
	public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
		// 时间
		List<LocalDate> dateList = new ArrayList<>();
		// 每天新增用户
		List<Integer> newUserList = new ArrayList<>();
		// 每天总用户
		List<Integer> totalUserList = new ArrayList<>();
		dateList.add(begin);
		while (!begin.equals(end)) {
			newUserList.add(userMapper.countNumber(LocalDateTime.of(begin, LocalTime.MIN), LocalDateTime.of(begin,
				LocalTime.MAX)));
			totalUserList.add(userMapper.countNumber(null, LocalDateTime.of(begin, LocalTime.MAX)));
			begin = begin.plusDays(1);
			dateList.add(begin);
		}
		newUserList.add(userMapper.countNumber(LocalDateTime.of(end, LocalTime.MIN), LocalDateTime.of(end,
			LocalTime.MAX)));
		totalUserList.add(userMapper.countNumber(null, LocalDateTime.of(end, LocalTime.MAX)));
		return new UserReportVO(StringUtils.join(dateList, ","), StringUtils.join(newUserList, ","),
			StringUtils.join(totalUserList, ","));
	}
	
	/**
	 * 订单统计
	 *
	 * @param begin
	 * @param end
	 * @return
	 */
	@Override
	public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
		// 时间
		List<LocalDate> dateList = new ArrayList<>();
		// 每日订单数
		List<Integer> orderCountList = new ArrayList<>();
		// 每日有效订单数
		List<Integer> validOrderCountList = new ArrayList<>();
		dateList.add(begin);
		while (!begin.equals(end)) {
			validOrderCountList.add(orderMapper.countNumber(5, LocalDateTime.of(begin, LocalTime.MIN),
				LocalDateTime.of(begin,
					LocalTime.MAX)));
			orderCountList.add(orderMapper.countNumber(null, LocalDateTime.of(begin, LocalTime.MIN), LocalDateTime.of(begin,
				LocalTime.MAX)));
			begin = begin.plusDays(1);
			dateList.add(begin);
		}
		validOrderCountList.add(orderMapper.countNumber(5, LocalDateTime.of(end, LocalTime.MIN), LocalDateTime.of(end,
			LocalTime.MAX)));
		orderCountList.add(orderMapper.countNumber(null, LocalDateTime.of(end, LocalTime.MIN), LocalDateTime.of(end,
			LocalTime.MAX)));
		// 订单总数
		Integer totalOrderCount = orderMapper.countNumber(null, null, null);
		// 有效订单数
		Integer validOrderCount = orderMapper.countNumber(5, null, null);
		// 订单完成率
		Double orderCompletionRate = 0.0;
		if (totalOrderCount != 0 && validOrderCount != 0) {
			orderCompletionRate = (double) validOrderCount / totalOrderCount;
		}
		
		return new OrderReportVO(StringUtils.join(dateList, ","), StringUtils.join(orderCountList, ","),
			StringUtils.join(validOrderCountList, ","), totalOrderCount, validOrderCount, orderCompletionRate);
	}
	
	/**
	 * 销售排行榜
	 *
	 * @param begin
	 * @param end
	 * @return
	 */
	@Override
	public SalesTop10ReportVO salesTop10(LocalDate begin, LocalDate end) {
		// 商品名称
		List<String> nameList = new ArrayList<>();
		// 销售数量
		List<Integer> numberList = new ArrayList<>();
		List<GoodsSalesDTO> salesTop10 = orderMapper.getSalesTop10(LocalDateTime.of(begin, LocalTime.MIN),
			LocalDateTime.of(end, LocalTime.MAX));
		salesTop10.forEach(e -> {
			nameList.add(e.getName());
			numberList.add(e.getNumber());
		});
		return new SalesTop10ReportVO(StringUtils.join(nameList, ","), StringUtils.join(numberList, ","));
	}
	
	/**
	 * 导出Excel
	 */
	@Override
	public void exportExcel(HttpServletResponse response) {
		LocalDateTime begin = LocalDateTime.of(LocalDate.now().minusDays(30), LocalTime.MIN);
		LocalDateTime end = LocalDateTime.of(LocalDate.now().minusDays(1), LocalTime.MAX);
		BusinessDataVO businessDataVO = workspaceService.businessData(begin, end);
		// 创建poi对象
		try (
			XSSFWorkbook sheets =
				new XSSFWorkbook(Objects.requireNonNull(this.getClass().getClassLoader().getResourceAsStream("template" +
					"/运营数据报表模板.xlsx")));
			// 通过输出流返回给客户端
			ServletOutputStream out = response.getOutputStream();
		) {
			XSSFSheet sheet = sheets.getSheet("Sheet1");
			// 填充数据
			sheet.getRow(1).getCell(1).setCellValue("统计时间：" + LocalDate.from(begin) + " - " + LocalDate.from(end));
			sheet.getRow(3).getCell(2).setCellValue(businessDataVO.getTurnover());
			sheet.getRow(3).getCell(4).setCellValue(businessDataVO.getOrderCompletionRate());
			sheet.getRow(3).getCell(6).setCellValue(businessDataVO.getNewUsers());
			sheet.getRow(4).getCell(2).setCellValue(businessDataVO.getValidOrderCount());
			sheet.getRow(4).getCell(4).setCellValue(businessDataVO.getUnitPrice());
			sheet.getRow(4).getCell(6).setCellValue(orderMapper.countNumber(null, begin, end));
			for (int i = 0; i < 30; i++) {
				LocalDateTime beginTime = LocalDateTime.of(LocalDate.from(begin.plusDays(i)), LocalTime.MIN);
				LocalDateTime endTime = LocalDateTime.of(LocalDate.from(begin.plusDays(i)), LocalTime.MAX);
				BusinessDataVO data = workspaceService.businessData(beginTime, endTime);
				XSSFRow row = sheet.getRow(7 + i);
				row.getCell(1).setCellValue(LocalDate.from(beginTime).toString());
				row.getCell(2).setCellValue(data.getTurnover());
				row.getCell(3).setCellValue(data.getValidOrderCount());
				row.getCell(4).setCellValue(data.getOrderCompletionRate());
				row.getCell(5).setCellValue(data.getUnitPrice());
				row.getCell(6).setCellValue(data.getNewUsers());
			}
			// 写入数据
			sheets.write(out);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		
	}
}
